package com.ai.dmc.index.web.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ai.dmc.index.common.bean.ExportBean;
import com.ai.dmc.index.common.bean.StaffSessBean;
import com.ai.dmc.index.web.bean.TblCell;
import com.ai.dmc.index.web.util.Constants;
import com.ai.dmc.index.web.util.SessionInfoUtil;
import com.ai.dmc.utils.export.ExportSvc;
import com.ai.dmc.utils.export.impl.PdfExportSvcImpl;
import com.ai.dmc.utils.export.impl.TxtExportSvcImpl;
import com.ai.dmc.utils.export.impl.XlsExportSvcImpl;
import com.ai.dmc.utils.string.StringUtil;
import com.ai.frame.bean.InputObject;
import com.ai.frame.bean.OutputObject;
import com.ai.frame.logger.Logger;
import com.ai.frame.logger.LoggerFactory;

import net.sf.json.JSONObject;

public class ExportAction extends BaseAction {
    private static final long serialVersionUID = 2021751412677646314L;
    private static final Logger logger = LoggerFactory.getActionLog(ExportAction.class);
    private  static final String  COLUMN_LENGTH = "column_length";
    private  static final String  DATA_HEAD = "data_head"; 
    
    private StaffSessBean session;
	private String userId;
	private boolean isAdmin;
	private String areaId;
	
	/**
	 * 
	 * @Description : 初始化
	 * @return void
	 * 
	 * @author : wucm
	 * @date : 2015年7月10日 上午9:41:28
	 * 
	 */
	public void init() {
		session = SessionInfoUtil.getStaffSessBean(
				this.getRequest().getSession());
		userId = session.getUserId();
		isAdmin = session.isAdmin();
		areaId = session.getAreaId();
	}
    
    /** Uniform Method Invocation **/
    public String execute() {
        logger.info("execute", "Start");
        this.init();
        InputObject inputObject = super.getInputObject();
        inputObject.getParams().put("userId", userId);
		inputObject.getParams().put("isAdmin", String.valueOf(isAdmin));
		inputObject.getParams().put("areaId", areaId);
		
		OutputObject object = this.getOutputObject();
        ExportBean bean = (ExportBean)object.getObject();
        inputObject.getParams().put("expType", bean.getExpType());
        String path = System.getProperty("user.dir").replace("bin", "webapps")+ File.separator;
        String fileName = exportFileByObject(inputObject, bean, path);
        try {
            downFile(path,fileName,super.getResponse(),super.getRequest());
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        logger.info("execute", "End");
        return null;
    }
    
    
    /**
     * �����ļ�
     * @throws UnsupportedEncodingException 
     */
    public  void downFile(String path,String fileName, HttpServletResponse response,HttpServletRequest request) throws UnsupportedEncodingException{
        response.setContentType("application/x-download");
        response.setContentType("application/OCTET-STREAM;charset=utf-8");
        //response.setHeader("contentType", "text/html; charset=utf-8");
       // String decodeFileName =  new String(fileName.getBytes("utf-8"), "ISO8859-1");
        String agent = request.getHeader("USER-AGENT");
        String decodeFileName = "";
        // ie  
        if (null != agent && -1 != agent.indexOf("MSIE") || null != agent  
                && -1 != agent.indexOf("Trident")) {
            decodeFileName = java.net.URLEncoder.encode(fileName, "UTF8");  
        }else {
            decodeFileName = new String(fileName.getBytes("utf-8"), "ISO8859-1");
        }
        response.setHeader("Content-Disposition", "attachment;filename=" + decodeFileName);
        File file = new File(path + File.separator + fileName);// Ҫ���ص��ļ�
        // �ͻ�������
         try {
            downFile2Client(file,response);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            file.delete();
        }
    }
    
    /**
     * �����ļ����ͻ���
     */
    public void downFile2Client(File file,HttpServletResponse response) throws Exception {
        OutputStream buffOut = null;
        FileInputStream buffIn = null;
        try {
            buffOut = response.getOutputStream();
            buffIn = new FileInputStream(file);
            int bytesRead = 0;// ��ǰ�����ֽ���
            byte[] buff = new byte[10240];// ����
            while ((bytesRead = buffIn.read(buff, 0, 10240)) != -1) {
                buffOut.write(buff, 0, bytesRead);
            }
            // ��������¼����¼����¼��״̬��Ϣ
            // request.getSession().removeAttribute("userDownInfo");
            buffOut.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // �����ʱ�ļ�
            if (buffOut != null) {
                try {
                    buffOut.close();
                } catch (IOException e) {
                    buffOut = null;
                }
                buffOut = null;
            }
            if (buffIn != null) {
                try {
                    buffIn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                buffIn = null;
            }
        }
    }
    
    @SuppressWarnings("unchecked")
    public String exportFileByObject(InputObject inputObject,ExportBean bean,String path) { {
        if(StringUtil.isEmpty(inputObject.getParams().get("expType"))) {
            throw new RuntimeException("输出格式有误");
        } else if(StringUtil.isEmpty(inputObject.getParams().get("expType"))) {
            throw new RuntimeException("输出路径有误");
        }
        //导出类型
        int expType = Integer.parseInt(inputObject.getParams().get("expType"));
        //生成excel时sheet名
        String title = bean.getSheetName();
        //报表头或者指标头
        String tblHeads = bean.getTitle();
        //文件路径
        //String path = System.getProperty("user.dir").replace("bin", "webapps")+ File.separator;
        //文件名称
        String fileName = bean.getFileName();
        String filePathName = path + fileName;
        //水印文字
        String waterMarkName = "";
        //如果只需要表头  为"Y"
        String  onlyHead  = "N";
        Map<String,Object> headList = getTblHead(tblHeads);
        ExportSvc iExportSvc = null;
        int column =  (Integer) headList.get(COLUMN_LENGTH);
        if(column <= 0) {
            throw new RuntimeException("报表头格式不对");
        }
        List<TblCell>[] arrays = (List<TblCell>[]) headList.get(DATA_HEAD);
        int columnNum = arrays.length;
        int colums = 0;
        if(columnNum>0){
            colums=arrays[0].size();
        }
        switch (expType) {
        case Constants.EXPORT_TYPE_PDF:
            fileName = fileName+".pdf";
            iExportSvc = new PdfExportSvcImpl(filePathName+".pdf", colums);
            break;
        case Constants.EXPORT_TYPE_TXT:
            fileName = fileName+".txt";
            iExportSvc = new TxtExportSvcImpl(filePathName+".txt");
            break;
        case Constants.EXPORT_TYPE_XLS:
            fileName = fileName+".xls";
            iExportSvc = new XlsExportSvcImpl(title, filePathName+".xls");
            break;
        default:
            throw new RuntimeException("无法匹配导出文件的类型");
        }
        // 创建表头
        List<TblCell>[] tblcellArray = (List<TblCell>[])headList.get(DATA_HEAD);
        List<Map<String,Object>>[] resultArrayList = new ArrayList[tblcellArray.length];
        for(int i=0;i<tblcellArray.length;i++){
            List<TblCell> tbls = tblcellArray[i];
            List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();
            for(TblCell tbl:tbls){
                Map<String,Object> paraMap = new HashMap<String,Object>();
                paraMap.put("colspan", tbl.getColspan());
                paraMap.put("rowspan", tbl.getRowspan());
                paraMap.put("alias", tbl.getAlias());
                resultList.add(paraMap);
            }
            resultArrayList[i] = resultList;
        }
        List<Map<String,Object>>[] tblcells = resultArrayList;
        iExportSvc.writeTblHead(tblcells, 1);
        //如果不只是需要表头
        
        if(!"Y".equals(onlyHead)) {
            // 写入数据
        	List<Object[]> listValue = new ArrayList<Object[]>();
            for(int i=0;i<bean.getDataList().size();i++){
            	Map<String, Object> listMap = bean.getDataList().get(i);
            	List<String> getMapValues = getMapValuesObject(listMap);
	        	Object[] ary1 = getMapValues.toArray();
	            listValue.add(ary1);
            }
            iExportSvc.writeData(listValue, 1);
        }
        // 写入文件关闭流
        iExportSvc.writeFile(false,waterMarkName);
       // Map<String,String> fileMap = new HashMap<String,String>();
       // fileMap.put("path", path);
       // fileMap.put("fileName", fileName);
        //outputObject.setBean(fileMap);
        
        return fileName;
        }
    }
    
    /*
     * 取出Map中的所有的值
     */
    @SuppressWarnings("rawtypes")
    public List<String> getMapValues(Map<String, String> objMap) {
        List<String> valuesList = new ArrayList<String>();
        Set set = objMap.entrySet();
        Iterator it = set.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Entry) it.next();
            valuesList.add(String.valueOf(entry.getValue()));
        }
        return valuesList;
    }
	/*
	 * 取出Map中的所有的值
	 */
	@SuppressWarnings("rawtypes")
	public List<String> getMapValuesObject(Map<String, Object> objMap) {
	    List<String> valuesList = new ArrayList<String>();
	    Set set = objMap.entrySet();
	    Iterator it = set.iterator();
	    while (it.hasNext()) {
	        Map.Entry entry = (Entry) it.next();
	        valuesList.add(String.valueOf(entry.getValue()));
	    }
	    return valuesList;
	}

    /**
     * 获取表头
     */
    public  Map<String,Object> getTblHead(String tblHead) {
        Map<String,Object> result = new HashMap<String,Object>();
        if (tblHead == null) {
            return result;
        }
//        String[] tblHeads = tblHead.split("::");
//        int maxRow = tblHeads.length;
        String[] tblHeads = tblHead.split("::");
        tblHead = tblHead.replaceAll("::", ";");
        int maxRow = 1;
        List<TblCell>[] arrays = new List[maxRow];
        // 初始化List<TblCell>[]
        int column = 1;
        for (int i = 0; i < maxRow; i++) {
            Map<String,Object> rowCell = getTbls(tblHead);
            int rowMaxcell = (Integer)rowCell.get("CURRENT_MAX_COLUMN");
            arrays[i] = (List<TblCell>)rowCell.get("ROW_TBL_CELL");
            column = rowMaxcell >= column ? rowMaxcell : column;
        }
        result.put(COLUMN_LENGTH, column);
        result.put(DATA_HEAD, arrays);
        return result;
    }
    
    public Map<String,Object> getTbls(String tbl) {
        int columns = 0;
        String[] tblcells = tbl.split(";");
        String cell = "";
        List<TblCell> resulttblcell = new ArrayList<TblCell>();
        for(String tblcell :tblcells) {
            int cellRow = 1;
            int cellColumn = 1;
            TblCell  talcell = new TblCell(tblcell);
            if(tblcell.contains("@")) {
                talcell = new TblCell(tblcell.split("@")[0]);
                cell = tblcell.split("@")[1];
                if(cell.indexOf("rowspan") != -1) {
                    cellRow = Integer.parseInt(tblcell.split("@")[1].split(":")[1]);
                } else {
                    cellColumn = Integer.parseInt(tblcell.split("@")[1].split(":")[1]);
                }
                columns +=cellColumn;
            }
            talcell.setColspan(cellColumn);
            talcell.setRowspan(cellRow);
            resulttblcell.add(talcell);
        }
        Map<String,Object> result = new HashMap<String,Object>();
        result.put("CURRENT_MAX_COLUMN", columns);
        result.put("ROW_TBL_CELL", resulttblcell);
        return result;
    }
     
    public String getProperty(String id) {
        return ResourceBundle.getBundle("config/initParam").getString(id);
    }
}
